package RmiInterface;

import java.beans.Visibility;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.String;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import nanoxml.XMLElement;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author marduke
 */
public class NodosImpl extends java.rmi.server.UnicastRemoteObject implements Nodos {

    Vector<String> Vecinos = new Vector<String>();
    String Visitados = "";
    String DirArchivo = "Biblioteca";

    public NodosImpl() throws java.rmi.RemoteException {
        super();
    }

    public NodosImpl(Vector<String> vecinos, String directorio) throws java.rmi.RemoteException {
        this.Vecinos = vecinos;
        this.DirArchivo = directorio;
    }

    public String Alcanzables(String visitados) throws RemoteException {

        String xmlre;
        XMLElement visXml = new XMLElement();

        try {

            visXml.parseString(visitados);
        } catch (NullPointerException e) {
            visXml.setName("visitados");
        }

        try {
            InetAddress addr = InetAddress.getLocalHost();
            XMLElement child = new XMLElement();
            child.setName("elemento");
            child.setAttribute("hostAddress", addr.getHostAddress());
            child.setAttribute("hostName", addr.getHostName());

            visXml.addChild(child);

        } catch (UnknownHostException e) {
            System.out.println("Error al obtener el host.");
        }


        xmlre = visXml.toString();

        int i = 0;
        try {
            for (Iterator it = Vecinos.iterator(); it.hasNext();) {


                String vecino = (String) it.next();

                if (!fueVisitado(xmlre, vecino)) {
                    try {
                        Nodos n = (Nodos) Naming.lookup("rmi://" + vecino + "/NodosService");


                        xmlre = n.Alcanzables(xmlre);
                    } catch (java.rmi.UnknownHostException e) {
                        System.out.println("El servidor " + vecino + " no existe.");
                    }

                }

            }

        } catch (Exception e) {
            System.out.println(e);
        }



        return xmlre;

    }

    private boolean fueVisitado(String xml, String vecino) {

        boolean retorno = false;

        try {

            XMLElement visitados = new XMLElement();
            visitados.parseString(xml);

            Enumeration childs = visitados.enumerateChildren();
            while (childs.hasMoreElements()) {
                XMLElement child = (XMLElement) childs.nextElement();
                String hostname = (String) child.getAttribute("hostName");
                String hostaddress = (String) child.getAttribute("hostAddress");



                if (hostaddress.equals(vecino) || hostname.equals(vecino)) {
                    return true;
                }
            }

        } catch (Exception uhE) {
        }

        return false;
    }

    public String Consulta(String consultaR,String visitados,String consulta,boolean tipo) throws RemoteException {

        XMLElement retorno = new XMLElement();
        XMLElement visitadoXml = new XMLElement();

        try {
            retorno.parseString(consultaR);
        } catch (Exception e) {
            retorno.setName("consulta");
        }



        Vector<String> vectorArchivos = new Vector();

        Vector<File> xmls = conseguirXmls(DirArchivo);
        try {
            consultaXmls(consulta, tipo, xmls);
        } catch (UnknownHostException ex) {
            Logger.getLogger(NodosImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return "";
    }

    private static Vector<File> conseguirXmls(String directorio) {
        File archivos[] = new File[1];
        Vector<File> vectorArchivos = new Vector();

        try {
            File dirFile = new File(directorio);
            if (dirFile.exists()) {
                if (dirFile.isDirectory()) {
                    // System.out.println("Es un directorio");
                    archivos = dirFile.listFiles();
                } else {
                    //System.out.println("No es un directorio");
                }
            } else {
                dirFile.mkdir();
                archivos = dirFile.listFiles();
            }

            for (int i = 0; i < archivos.length; i++) {
                File file = archivos[i];
                String nFile = file.getName();

                if (nFile.contains(".xml")) {
                    vectorArchivos.add(file);
                }
            }

            for (Iterator<File> it = vectorArchivos.iterator();
                    it.hasNext();) {
                File string = it.next();
                System.out.println(string.getName());
            }
        } catch (Exception e) {
        }

        return vectorArchivos;

    }

    // Si el tipo es true es por titulo si es false es por clave
    private static String consultaXmls(String consulta, boolean tipo, Vector<File> xmls) throws UnknownHostException {

        XMLElement consultaResultado = new XMLElement();
        consultaResultado.setName("elemento");

        InetAddress localhost = InetAddress.getLocalHost();

        consultaResultado.setAttribute("hostname", localhost.getHostName());
        consultaResultado.setAttribute("hostaddress", localhost.getHostAddress());

        for (Iterator<File> it = xmls.iterator(); it.hasNext();) {
            File file = it.next();

            if (consultaXml(consulta, tipo, file)) {
                addFileToXml(consultaResultado, file);
            }

        }

        System.out.println(consultaResultado.toString());

        return consultaResultado.toString();
    }

    private static boolean consultaXml(String consulta, boolean tipo, File xml) {

        try {

            XMLElement fileXml = new XMLElement();
            FileReader reader = new FileReader(xml);
            fileXml.parseFromReader(reader);

            Enumeration<XMLElement> children = fileXml.enumerateChildren();
            while (children.hasMoreElements()) {
                XMLElement child = children.nextElement();

                if (child.getName().equals("titulo") && tipo) {

                    String contain = child.getContent();
                    if (contain.contains(consulta)) {
                        return true;
                    }


                }

                if (child.getName().equals("palabrasClave") && !tipo) {

                    Enumeration<XMLElement> palabrasClaves = child.enumerateChildren();
                    while (palabrasClaves.hasMoreElements()) {
                        XMLElement elemento = palabrasClaves.nextElement();
                        String palabra = (String) elemento.getAttribute("palabra");
                        if (palabra.contains(consulta)) {
                            return true;
                        }
                    }
                }

            }


        } catch (FileNotFoundException e) {
        } catch (IOException e) {
        }

        return false;
    }

    private static void addFileToXml(XMLElement consulta, File file) {

        try {
            FileReader reader = new FileReader(file);
            XMLElement archivo = new XMLElement();
            archivo.parseFromReader(reader);

            consulta.addChild(archivo);
        } catch (Exception e) {
        }

    }
}
